package com.vm.osm.business.service.impl;

import com.github.pagehelper.StringUtil;
import com.vm.osm.business.common.exception.BusinessException;
import com.vm.osm.business.dao.OsmLogicNodeMapper;
import com.vm.osm.business.dto.req.logic_node.AddLogicNodeReq;
import com.vm.osm.business.dto.req.logic_node.UpdateLogicNodeReq;
import com.vm.osm.business.dto.rsp.logic_node.LogicNodeDetail;
import com.vm.osm.business.dto.rsp.logic_node.LogicNodeTree;
import com.vm.osm.business.entity.OsmLogicNode;
import com.vm.osm.business.entity.OsmLogicNodeAttr;
import com.vm.osm.business.service.IOsmLogicNodeAttrService;
import com.vm.osm.business.service.IOsmLogicNodeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class OsmLogicNodeServiceImpl
        extends AbstractServiceImpl<OsmLogicNode, String> implements IOsmLogicNodeService {
    @Autowired
    private OsmLogicNodeMapper mapper;
    @Autowired
    private IOsmLogicNodeAttrService osmLogicNodeAttrService;

    public OsmLogicNodeServiceImpl(OsmLogicNodeMapper mapper) {
        super(mapper);
        this.mapper = mapper;
    }

    @Override
    @Transactional
    public void add(AddLogicNodeReq request) {
        if (null == request) throw new BusinessException("请求参数为空");
        final Date NOW = new Date();
        OsmLogicNode node = new OsmLogicNode();
        BeanUtils.copyProperties(request, node);
        // 判断节点树深度，设置节点深度值
        if (StringUtil.isNotEmpty(request.getParent_id())) {
            OsmLogicNode parent = selectByPrimaryKey(request.getParent_id());
            if (null == parent) throw new BusinessException("父节点不存在");
            if (parent.getDepth() >= 4) throw new BusinessException("节点深度不得超过5");
            node.setDepth((byte) (parent.getDepth() + 1));
        } else node.setDepth((byte) 0);
        node.setId(UUID.randomUUID().toString());
        node.setNode_code(UUID.randomUUID().toString());
        node.setCreate_time(NOW);
        node.setModified_time(NOW);
        insertSelective(node);
        // 设置节点属性
        if (null == request.getAttrs() || request.getAttrs().size() <= 0) return;
        request.getAttrs().forEach(item -> {
            OsmLogicNodeAttr attr = new OsmLogicNodeAttr();
            attr.setAttr_id(item.getAttr_id());
            attr.setAttr_value(item.getAttr_val());
            attr.setNode_id(node.getId());
            attr.setId(UUID.randomUUID().toString());
            attr.setCreate_time(NOW);
            attr.setModified_time(NOW);
            osmLogicNodeAttrService.insertSelective(attr);
        });
    }

    @Override
    @Transactional
    public void update(UpdateLogicNodeReq request) {
        if (null == request) throw new BusinessException("请求参数为空");
        final Date NOW = new Date();
        // 更新节点信息
        OsmLogicNode node = selectByPrimaryKey(request.getId());
        if (null == node) throw new BusinessException("节点不存在");
        OsmLogicNode temp = new OsmLogicNode();
        BeanUtils.copyProperties(request, temp);
        temp.setModified_time(NOW);
        updateByPrimaryKey(temp);
        // 删除旧的属性记录
        osmLogicNodeAttrService.deleteByNodeId(request.getId());
        // 添加节点属性记录
        if (null == request.getAttrs() || request.getAttrs().size() <= 0) return;
        request.getAttrs().forEach(item -> {
            OsmLogicNodeAttr attr = new OsmLogicNodeAttr();
            attr.setAttr_id(item.getAttr_id());
            attr.setAttr_value(item.getAttr_val());
            attr.setNode_id(request.getId());
            attr.setId(UUID.randomUUID().toString());
            attr.setCreate_time(NOW);
            attr.setModified_time(NOW);
            osmLogicNodeAttrService.insertSelective(attr);
        });
    }

    @Override
    @Transactional
    public void delete(String id) {
        OsmLogicNode node = selectByPrimaryKey(id);
        if (null == node) throw new BusinessException("节点不存在");
        // 删除节点
        deleteByPrimaryKey(id);
        // 删除节点对应属性
        osmLogicNodeAttrService.deleteByNodeId(id);
        // todo 请求相关设备的关联信息
    }

    @Override
    public List<OsmLogicNode> find(Map<String, Object> params) {
        return mapper.find(params);
    }

    @Override
    public void tree(LogicNodeTree root, String id, String node_name) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        params.put("node_name_blur", node_name);
        List<OsmLogicNode> list = find(params);
        list.forEach(item -> {
            if (null == LogicNodeTree.MAP.get()) LogicNodeTree.MAP.set(new HashMap<>());
            LogicNodeTree node = LogicNodeTree.MAP.get().get(item.getId());
            if (null == node) {
                node = new LogicNodeTree();
                BeanUtils.copyProperties(item, node);
                LogicNodeTree.MAP.get().put(item.getId(), node);
            }
            if (StringUtils.isEmpty(item.getParent_id())) {
                if (null == root.getChildren()) root.setChildren(new LinkedList<>());
                if (root.getChildren().stream().noneMatch(child -> child.getId().equals(item.getId()))) {
                    root.getChildren().add(node);
                }
            } else {
                LogicNodeTree parent = LogicNodeTree.MAP.get().get(item.getParent_id());
                if (null == parent) {
                    tree(root, item.getParent_id(), null);
                    parent = LogicNodeTree.MAP.get().get(item.getParent_id());
                }
                if (null == parent.getChildren()) parent.setChildren(new LinkedList<>());
                if (parent.getChildren().stream().noneMatch(child -> child.getId().equals(item.getId()))) {
                    parent.getChildren().add(node);
                }
            }
        });
    }

    @Override
    public LogicNodeDetail detail(String id) {
        OsmLogicNode node = selectByPrimaryKey(id);
        if (null == node) throw new BusinessException("节点不存在");
        LogicNodeDetail detail = new LogicNodeDetail();
        BeanUtils.copyProperties(node, detail);
        Map<String, Object> params = new HashMap<>();
        params.put("node_id", id);
        List<OsmLogicNodeAttr> attrs = osmLogicNodeAttrService.find(params);
        if (null != attrs) {
            detail.setAttrs(new LinkedList<>());
            attrs.forEach(record -> {
                LogicNodeDetail.AttrItem item = new LogicNodeDetail.AttrItem();
                BeanUtils.copyProperties(record, item);
                detail.getAttrs().add(item);
            });
        }
        return detail;
    }
}
